package top.codef.crypt.aes;

import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Base64;

public class AESUtils {

	public static String genericKey() {
		return genericKey(128);
	}

	public static String genericKey(int size) {
		try {
			String base64 = Base64.encodeBase64String(AESKeyPair.genericKey(size));
			return base64;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	public static byte[] encrypt(byte[] content, String key) {
		AESKeyPair aesKeyPair = AESKeyPair.instance(Base64.decodeBase64(key));
		try {
			return aesKeyPair.encrypt(content);
		} catch (Exception e) {
			throw new AESException("AES加密异常", e);
		}
	}

	public static byte[] decrypt(byte[] secContent, String key) {
		AESKeyPair aesKeyPair = AESKeyPair.instance(Base64.decodeBase64(key));
		try {
			return aesKeyPair.decrypt(secContent);
		} catch (Exception e) {
			throw new AESException("AES解密异常", e);
		}
	}

	public static byte[] encrypt(byte[] content, String key, AesAlgorithm aesAlgorithm) {
		AESKeyPair aesKeyPair = AESKeyPair.instance(Base64.decodeBase64(key), aesAlgorithm);
		try {
			return aesKeyPair.encrypt(content);
		} catch (Exception e) {
			throw new AESException("AES加密异常", e);
		}
	}

	public static byte[] decrypt(byte[] secContent, String key, AesAlgorithm aesAlgorithm) {
		AESKeyPair aesKeyPair = AESKeyPair.instance(Base64.decodeBase64(key), aesAlgorithm);
		try {
			return aesKeyPair.decrypt(secContent);
		} catch (Exception e) {
			throw new AESException("AES解密异常", e);
		}
	}

	public static String encrypt2Base64(byte[] content, String key) {
		byte[] secContent = encrypt(content, key);
		return Base64.encodeBase64String(secContent);
	}

	public static String decrypt2Base64(byte[] secContent, String key) {
		byte[] content = decrypt(secContent, key);
		return new String(content, Charset.forName("utf8"));
	}

	public static String encrypt2Base64(byte[] content, String key, AesAlgorithm cryptAlgorithm) {
		byte[] secContent = encrypt(content, key, cryptAlgorithm);
		return Base64.encodeBase64String(secContent);
	}

	public static String decrypt2Base64(byte[] secContent, String key, AesAlgorithm cryptAlgorithm) {
		byte[] content = decrypt(secContent, key, cryptAlgorithm);
		return new String(content, Charset.forName("utf8"));
	}

	public static String encrypt2Base64(String content, String key) {
		return encrypt2Base64(content.getBytes(Charset.forName("utf8")), key);
	}

	public static String decrypt2Base64(String secContent, String key) {
		return decrypt2Base64(Base64.decodeBase64(secContent), key);
	}

	public static String encryptAES128CBCPKS72Base64(String content, String key, String iv) {
		return encrypt(AesAlgorithm.AES_128_CBC_PKCS7, content, key, iv);
	}

	public static String decryptAES128CBCPKS72Str(String secContent, String key, String iv) {
		return decrypt(AesAlgorithm.AES_128_CBC_PKCS7, secContent, key, iv);
	}

	public static String encrypt(AesAlgorithm aesAlgorithm, String content, String key, String iv) {
		AESAdvancedKeyPair advancedKeyPair = AESAdvancedKeyPair.instance(aesAlgorithm, Base64.decodeBase64(key),
				Base64.decodeBase64(iv), Cipher.ENCRYPT_MODE);
		byte[] contentByte = content.getBytes(StandardCharsets.UTF_8);
		String base64 = Base64.encodeBase64String(advancedKeyPair.encrypt(contentByte));
		return base64;
	}

	public static String decrypt(AesAlgorithm aesAlgorithm, String secContent, String key, String iv) {
		AESAdvancedKeyPair advancedKeyPair = AESAdvancedKeyPair.instance(aesAlgorithm, Base64.decodeBase64(key),
				Base64.decodeBase64(iv), Cipher.DECRYPT_MODE);
		byte[] contentByte = Base64.decodeBase64(secContent);
		String content = new String(advancedKeyPair.decrypt(contentByte), StandardCharsets.UTF_8);
		return content;
	}

	public static String encrypt(AesAlgorithm aesAlgorithm, String content, String key, String iv,
			String additionAuthData) {
		AESAdvancedKeyPair advancedKeyPair = AESAdvancedKeyPair.instance(aesAlgorithm, Base64.decodeBase64(key),
				Base64.decodeBase64(iv), Base64.decodeBase64(additionAuthData), Cipher.ENCRYPT_MODE);
		byte[] contentByte = content.getBytes(StandardCharsets.UTF_8);
		String base64 = Base64.encodeBase64String(advancedKeyPair.encrypt(contentByte));
		return base64;
	}

	public static String decrypt(AesAlgorithm aesAlgorithm, String secContent, String key, String iv,
			String additionAuthData) {
		AESAdvancedKeyPair advancedKeyPair = AESAdvancedKeyPair.instance(aesAlgorithm, Base64.decodeBase64(key),
				Base64.decodeBase64(iv), Base64.decodeBase64(additionAuthData), Cipher.DECRYPT_MODE);
		byte[] contentByte = Base64.decodeBase64(secContent);
		String content = new String(advancedKeyPair.decrypt(contentByte), StandardCharsets.UTF_8);
		return content;
	}

	public static String encrypt(AesAlgorithm aesAlgorithm, byte[] content, byte[] key, byte[] iv,
			byte[] additionAuthData) {
		AESAdvancedKeyPair advancedKeyPair = AESAdvancedKeyPair.instance(aesAlgorithm, key, iv, additionAuthData,
				Cipher.ENCRYPT_MODE);
		String base64 = Base64.encodeBase64String(advancedKeyPair.encrypt(content));
		return base64;
	}

	public static String decrypt(AesAlgorithm aesAlgorithm, byte[] secContent, byte[] key, byte[] iv,
			byte[] additionAuthData) {
		AESAdvancedKeyPair advancedKeyPair = AESAdvancedKeyPair.instance(aesAlgorithm, key, iv, additionAuthData,
				Cipher.DECRYPT_MODE);
		String content = new String(advancedKeyPair.decrypt(secContent), StandardCharsets.UTF_8);
		return content;
	}

}
